package cn.z2huo.demo.hello.core.common;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.stream.Collectors;

/**
 * <p>
 *
 * @author z2huo
 */
public interface HolderManager {

    ServiceLoader<HolderManager> HOLDER_MANAGER = ServiceLoader.load(HolderManager.class);

    static Map<String, Object> get() {

        HashMap<String, Object> contextMap = new HashMap<>();
        for (HolderManager manager : HOLDER_MANAGER) {
            contextMap.putAll(manager.getAll());
        }
        contextMap.entrySet().removeIf(entry -> entry.getValue() == null);
        return contextMap;
    }

    default Map<String, Object> getAll() {
        Class<? extends HolderManager> implClass = this.getClass();
        return Arrays.stream(this.getClass().getDeclaredFields())
                .filter(field -> field.getDeclaringClass() == ThreadLocal.class && Modifier.isStatic(field.getModifiers()))
                .peek(field -> field.setAccessible(true))
                .collect(Collectors.toMap(f -> implClass.getSimpleName() + "#" + f.getName(),
                        f -> {
                            try {
                                return ((ThreadLocal<?>) f.get(null)).get();
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        })
                );
    }

}
